// vim: ff=unix : foldmethod=marker : foldmarker=<<<,>>>
/*
 File: pointer.h
 Product: NOL Base
 Creating date: 06/01/2005 15:14
 Remark: 
*/
#ifndef lite_pointerH
#define lite_pointerH

#include <string.h>
#include <stddef.h>
#include "lite/integer.h"

typedef void v_t; //void
typedef v_t * v_p; typedef v_p * v_pp;

#define R_t(pair) v_p pair; i_t pair##Size
#define R_p(pair) v_p pair, i_t pair##Size
#define R_pp(pair) v_pp pair, i_p pair##Size

#define WARP(type,var,value) type var=(type)(value)
#define CAST(type,value) ((type)(value))

//add to or shift by any pointer for given size in bytes
#define padd(ptr,size) ((v_p)(((i1_p)(ptr))+(size)))
#define ptad(ptr,type) ((v_p)(((i1_p)(ptr))+sizeof(type)))

#ifdef __cplusplus
#define psht(ptr,size) ((v_p)(((i1_t &)(ptr))+=(size)))
#else
#define psht(ptr,size) ((v_p)(((i1_p)(ptr))+=(size)))
#endif

#define ptsh(ptr,type) ((v_p)(((i1_p)(ptr))+=sizeof(type)))
#define ptpe(ptr,size,type) ((type)padd(ptr,size))
#define penv(ptr,type,field) ((type *)padd(ptr,-offsetof(type,field)))
#define pdis(from,to) ((i_t)(((i1_p)(to))-((i1_p)(from))))

//mem move/copy/set to NOL mapping
#define mset memset
#define mzero(dst,qnt) mset(dst,0,qnt)
#define mcmp memcmp

#define mcpyi memcpy
#define mcpyd memmove
#define mcpy memmove

inline_q v_t masg(v_p dst, v_p src, i_t qnt) { memcpy(dst,src,qnt); }
#define masg4(dst,src) *(i4_p)(dst)=*(i4_p)(src)
#define masg8(dst,src) \
 do { \
  i4_p __s=(i4_p)(src), __d=(i4_p)(dst); \
  __d[0]=__s[0]; __d[1]=__s[1]; \
  } while(0)
#define masg16(dst,src) \
 do {\
  i4_p __s=(i4_p)(src), __d=(i4_p)(dst); \
  __d[0]=__s[0]; __d[1]=__s[1]; __d[2]=__s[2]; __d[3]=__s[3];\
  } while(0)
#define masg20(dst,src) \
 do {\
  i4_p __s=(i4_p)(src), __d=(i4_p)(dst); \
  __d[0]=__s[0]; __d[1]=__s[1]; __d[2]=__s[2]; __d[3]=__s[3];\
  __d[4]=__s[4]; __d[5]=__s[5];\
  } while(0)


#define mswp4(dst,src) \
 do {\
  i4_p __d=(i4_p)(dsr), __s=(i4_p)(src);\
  i4_t __h=*__s; *__s=*__d; *__d=__h;\
  } while(0)
#define mswp8(dst,src) \
 do {\
  i4_p __d=(i4_p)(dst), __s=(i4_p)(src);\
  i4_t __h=__s[0]; __s[0]=__d[0]; __d[0]=__h;\
       __h=__s[1]; __s[1]=__d[1]; __d[1]=__h;\
  } while(0)
#define mswp16(dst,src) \
 do {\
  i4_p __d=(i4_p)(dst), __s=(i4_p)(src);\
  i4_t __h=__s[0]; __s[0]=__d[0]; __d[0]=__h;\
       __h=__s[1]; __s[1]=__d[1]; __d[1]=__h;\
       __h=__s[2]; __s[2]=__d[2]; __d[2]=__h;\
       __h=__s[3]; __s[3]=__d[3]; __d[3]=__h;\
  } while(0)
#define mswp20(dst,src) \
 do {\
  i4_p __d=(i4_p)(dst), __s=(i4_p)(src);\
  i4_t __h=__s[0]; __s[0]=__d[0]; __d[0]=__h;\
       __h=__s[1]; __s[1]=__d[1]; __d[1]=__h;\
       __h=__s[2]; __s[2]=__d[2]; __d[2]=__h;\
       __h=__s[3]; __s[3]=__d[3]; __d[3]=__h;\
       __h=__s[4]; __s[4]=__d[4]; __d[4]=__h;\
       __h=__s[5]; __s[5]=__d[5]; __d[5]=__h;\
  } while(0)
/*
mpos
*/

// swap <<<
inline_q v_t mswp(v_p dst, v_p src, i_t qnt) {
 i1_p s1, d1; i_p s,d,sentinel;
 i_t q,r;
 s=(i_p)src; d=(i_p)dst; q=qnt; r=q&(sizeof(i_t)-1);
 sentinel=(i_p)(((i1_p)s)+q-r);
 while (s<sentinel) { i_t halt=*s; *(s++)=*d; *(d++)=halt; };
 s1=(i1_p)s; d1=(i1_p)d;
 while (r-->0) { i1_t halt=*s1; *(s1++)=*d1; *(d1++)=halt; }
 };

#define lite_swap(src,dst,qnt) \
 do { \
  i1_p __s1, __d1; i_p __s,__d,__sentinel; \
  i_t __q,__r; \
  __s=(i_p)(src); __d=(i_p)(dst); __q=(qnt); \
  __r=__q&0x03; \
  __sentinel=(i_p)((i1_p)(__s)+__q-__r); \
  while (__s<__sentinel) { i_t halt=*__s; *(__s++)=*__d; *(__d++)=halt; }; \
  __s1=(i1_p)__s; __d1=(i1_p)__d;\
  while (__r-->0) { i1_t halt=*__s1; *(__s1++)=*__d1; *(__d1++)=halt; } \
  } while(0)
//>>>

#endif
